`
https://leetcode.cn/problems/partition-to-k-equal-sum-subsets/
`
/**
 * @param {number[]} nums
 * @param {number} k
 * @return {boolean}
 */
var canPartitionKSubsets = function (nums, k) {
  // 计算数组的总和
  const sum = nums.reduce((pre, cur) => pre + cur, 0);
  // 如果总和不能被k整除，则无法划分为k个相等的子集
  if (sum % k != 0) return false;
  // 每个子集的目标和
  const target = sum / k;
  // 将数组从大到小排序，更好地命中剪枝，优化回溯时的效率
  nums.sort((a, b) => b - a);
  // 初始化k个桶，每个桶的初始和为 0
  const buckets = new Array(k).fill(0);

  // 定义回溯函数，尝试将数字放入桶中
  const backtrack = (index) => {
    // 如果所有数字都被放入桶中，返回true
    if (index == nums.length) {
      return true;
    }
    // 遍历每个桶，尝试将当前数字放入
    for (let i = 0; i < k; i++) {
      // 如果当前桶和上一个桶的值相同，跳过，避免重复计算
      if (i > 0 && buckets[i] == buckets[i - 1]) continue;
      // 如果当前桶加上当前数字超过目标和，跳过
      if (buckets[i] + nums[index] > target) continue;
      // 将当前数字放入桶中
      buckets[i] += nums[index];
      // 递归处理下一个数字，如果成功，返回true
      if (backtrack(index + 1)) return true;
      // 回溯，将当前数字移出桶
      buckets[i] -= nums[index];
    }
    // 如果所有桶都无法放入当前数字，返回false
    return false;
  };
  // 从第0个数字开始回溯
  return backtrack(0);
};